diff options
author | Mike Buland <eichlan@xagasoft.com> | 2011-12-30 22:40:21 -0700 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2011-12-30 22:40:21 -0700 |
commit | 8bcb83035607371a2326374665e9cc56c662a783 (patch) | |
tree | b46c73e24edff0693f3e4c678bafad874ee9f21e | |
parent | ba7897ebadbc03d99200fda03a574a57b650e429 (diff) | |
download | stage-8bcb83035607371a2326374665e9cc56c662a783.tar.gz stage-8bcb83035607371a2326374665e9cc56c662a783.tar.bz2 stage-8bcb83035607371a2326374665e9cc56c662a783.tar.xz stage-8bcb83035607371a2326374665e9cc56c662a783.zip |
Wow, dictionaries, nested dictionaries, for loops
They all work. I still think I should change the lists to arrays in the
backend so they can be indexed as well as iterated over and appended to.
-rw-r--r-- | src/astnode.cpp | 1 | ||||
-rw-r--r-- | src/astnode.h | 1 | ||||
-rw-r--r-- | src/functiondisplay.cpp | 34 | ||||
-rw-r--r-- | src/functiondisplay.h | 3 | ||||
-rw-r--r-- | src/gamebuilder.cpp | 2 | ||||
-rw-r--r-- | src/gamestate.cpp | 125 | ||||
-rw-r--r-- | src/gamestate.h | 4 | ||||
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/parser.y | 25 | ||||
-rw-r--r-- | src/variable.cpp | 35 | ||||
-rw-r--r-- | src/variable.h | 14 | ||||
-rw-r--r-- | test.stage | 92 |
12 files changed, 287 insertions, 51 deletions
diff --git a/src/astnode.cpp b/src/astnode.cpp index 84f6845..2417968 100644 --- a/src/astnode.cpp +++ b/src/astnode.cpp | |||
@@ -45,6 +45,7 @@ Bu::Formatter &operator<<( Bu::Formatter &f, AstNode::Type t ) | |||
45 | case AstNode::tReturn: return f << "tReturn"; | 45 | case AstNode::tReturn: return f << "tReturn"; |
46 | case AstNode::tAppend: return f << "tAppend"; | 46 | case AstNode::tAppend: return f << "tAppend"; |
47 | case AstNode::tInsert: return f << "tInsert"; | 47 | case AstNode::tInsert: return f << "tInsert"; |
48 | case AstNode::tIndex: return f << "tIndex"; | ||
48 | 49 | ||
49 | case AstNode::tLeafLiteral: return f << "!tLeafLiteral!"; | 50 | case AstNode::tLeafLiteral: return f << "!tLeafLiteral!"; |
50 | case AstNode::tVarName: return f << "tVarName"; | 51 | case AstNode::tVarName: return f << "tVarName"; |
diff --git a/src/astnode.h b/src/astnode.h index 58c4a42..a1215ed 100644 --- a/src/astnode.h +++ b/src/astnode.h | |||
@@ -35,6 +35,7 @@ public: | |||
35 | tReturn = 0x01000017, | 35 | tReturn = 0x01000017, |
36 | tAppend = 0x01000018, | 36 | tAppend = 0x01000018, |
37 | tInsert = 0x01000019, | 37 | tInsert = 0x01000019, |
38 | tIndex = 0x0100001A, | ||
38 | 39 | ||
39 | tLeafLiteral = 0x02000000, | 40 | tLeafLiteral = 0x02000000, |
40 | tVarName = 0x02000001, | 41 | tVarName = 0x02000001, |
diff --git a/src/functiondisplay.cpp b/src/functiondisplay.cpp index fa5b79c..4790844 100644 --- a/src/functiondisplay.cpp +++ b/src/functiondisplay.cpp | |||
@@ -15,7 +15,37 @@ FunctionDisplay::~FunctionDisplay() | |||
15 | 15 | ||
16 | void FunctionDisplay::call( class GameState &gState ) | 16 | void FunctionDisplay::call( class GameState &gState ) |
17 | { | 17 | { |
18 | Variable v = gState.popDeref(); | 18 | Bu::String s = gState.popDeref().to( Variable::tString ).getString(); |
19 | sio << "Display: " << v << sio.nl; | 19 | |
20 | sio << format( s ) << sio.nl; | ||
21 | // sio << "Display: " << v << sio.nl; | ||
22 | } | ||
23 | |||
24 | Bu::String FunctionDisplay::format( const Bu::String &sSrc ) | ||
25 | { | ||
26 | Bu::String sRet; | ||
27 | bool bWs = true; | ||
28 | Bu::String::const_iterator i = sSrc.begin(); | ||
29 | |||
30 | while( i ) | ||
31 | { | ||
32 | for(; i; i++ ) | ||
33 | { | ||
34 | if( *i != ' ' && *i != '\t' && *i != '\n' && *i != '\r' ) | ||
35 | break; | ||
36 | } | ||
37 | for(; i; i++ ) | ||
38 | { | ||
39 | if( i == ' ' || i == '\t' || *i == '\n' || *i == '\r' ) | ||
40 | { | ||
41 | sRet.append(' '); | ||
42 | break; | ||
43 | } | ||
44 | |||
45 | sRet.append( *i ); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | return sRet; | ||
20 | } | 50 | } |
21 | 51 | ||
diff --git a/src/functiondisplay.h b/src/functiondisplay.h index 3b7e828..48e51fe 100644 --- a/src/functiondisplay.h +++ b/src/functiondisplay.h | |||
@@ -11,6 +11,9 @@ public: | |||
11 | 11 | ||
12 | virtual Bu::String getName() const { return "display"; } | 12 | virtual Bu::String getName() const { return "display"; } |
13 | virtual void call( class GameState &gState ); | 13 | virtual void call( class GameState &gState ); |
14 | |||
15 | private: | ||
16 | Bu::String format( const Bu::String &sSrc ); | ||
14 | }; | 17 | }; |
15 | 18 | ||
16 | #endif | 19 | #endif |
diff --git a/src/gamebuilder.cpp b/src/gamebuilder.cpp index 791ba6b..d04a642 100644 --- a/src/gamebuilder.cpp +++ b/src/gamebuilder.cpp | |||
@@ -185,7 +185,7 @@ void GameBuilder::closeCommand() | |||
185 | { | 185 | { |
186 | pCurCmd->setAst( pCurRoot ); | 186 | pCurCmd->setAst( pCurRoot ); |
187 | pCurRoot = pCurNode = NULL; | 187 | pCurRoot = pCurNode = NULL; |
188 | // pCurCmd->print(); | 188 | //pCurCmd->print(); |
189 | if( bGlobal ) | 189 | if( bGlobal ) |
190 | { | 190 | { |
191 | pGame->csGlobal.addCommand( pCurCmd ); | 191 | pGame->csGlobal.addCommand( pCurCmd ); |
diff --git a/src/gamestate.cpp b/src/gamestate.cpp index e8df070..bd3e638 100644 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp | |||
@@ -120,7 +120,7 @@ void GameState::delVariable( const Bu::String &sName, ScopeId id ) | |||
120 | throw Bu::ExceptionBase("Really bad scopeid passed into getVariable"); | 120 | throw Bu::ExceptionBase("Really bad scopeid passed into getVariable"); |
121 | } | 121 | } |
122 | 122 | ||
123 | Variable GameState::getVariable( const Bu::String &sName, ScopeId id ) | 123 | Variable &GameState::getVariable( const Bu::String &sName, ScopeId id ) |
124 | { | 124 | { |
125 | try | 125 | try |
126 | { | 126 | { |
@@ -174,12 +174,62 @@ void GameState::setVariable( const Bu::String &sName, const Variable &v, | |||
174 | throw Bu::ExceptionBase("Really bad scopeid passed into setVariable"); | 174 | throw Bu::ExceptionBase("Really bad scopeid passed into setVariable"); |
175 | } | 175 | } |
176 | 176 | ||
177 | Variable GameState::deref( const Variable &src ) | 177 | Variable &GameState::deref( Variable &src, bool bCreate ) |
178 | { | 178 | { |
179 | if( src.getType() == Variable::tVariable ) | 179 | if( src.getType() == Variable::tVariable ) |
180 | { | 180 | { |
181 | VariableRef r = src.getVariableRef(); | 181 | VariableRef r = src.getVariableRef(); |
182 | return getVariable( r.sName, r.sid ); | 182 | try |
183 | { | ||
184 | switch( r.sid ) | ||
185 | { | ||
186 | case sidLocal: | ||
187 | return lsLocal.peek()->get( r.sName ); | ||
188 | |||
189 | case sidGlobal: | ||
190 | return sGlobal.get( r.sName ); | ||
191 | |||
192 | case sidPlayer: | ||
193 | return sPlayer.get( r.sName ); | ||
194 | |||
195 | case sidSituation: | ||
196 | return hsSituation.get( sCurSituation )->get( r.sName ); | ||
197 | } | ||
198 | } | ||
199 | catch( Bu::HashException &e ) | ||
200 | { | ||
201 | if( bCreate ) | ||
202 | { | ||
203 | switch( r.sid ) | ||
204 | { | ||
205 | case sidLocal: | ||
206 | lsLocal.peek()->insert( r.sName, Variable() ); | ||
207 | return lsLocal.peek()->get( r.sName ); | ||
208 | |||
209 | case sidGlobal: | ||
210 | sGlobal.insert( r.sName, Variable() ); | ||
211 | return sGlobal.get( r.sName ); | ||
212 | |||
213 | case sidPlayer: | ||
214 | sPlayer.insert( r.sName, Variable() ); | ||
215 | return sPlayer.get( r.sName ); | ||
216 | |||
217 | case sidSituation: | ||
218 | hsSituation.get( sCurSituation )->insert( r.sName, Variable() ); | ||
219 | return hsSituation.get( sCurSituation )->get( r.sName ); | ||
220 | } | ||
221 | } | ||
222 | else | ||
223 | { | ||
224 | throw Bu::ExceptionBase("No %d variable named %s found.", | ||
225 | r.sid, | ||
226 | r.sName.getStr() ); | ||
227 | } | ||
228 | } | ||
229 | } | ||
230 | else if( src.getType() == Variable::tVarPtr ) | ||
231 | { | ||
232 | return *src.getVariablePtr(); | ||
183 | } | 233 | } |
184 | return src; | 234 | return src; |
185 | } | 235 | } |
@@ -231,6 +281,10 @@ Variable GameState::popDeref() | |||
231 | VariableRef r = v.getVariableRef(); | 281 | VariableRef r = v.getVariableRef(); |
232 | return getVariable( r.sName, r.sid ); | 282 | return getVariable( r.sName, r.sid ); |
233 | } | 283 | } |
284 | else if( v.getType() == Variable::tVarPtr ) | ||
285 | { | ||
286 | return *v.getVariablePtr(); | ||
287 | } | ||
234 | return v; | 288 | return v; |
235 | } | 289 | } |
236 | 290 | ||
@@ -294,9 +348,11 @@ void GameState::parse( const AstBranch::NodeList &lCode ) | |||
294 | case AstNode::tStore: | 348 | case AstNode::tStore: |
295 | { | 349 | { |
296 | Variable y = popDeref(); | 350 | Variable y = popDeref(); |
297 | Variable dst = pop(); | 351 | deref( lStack.peek(), true ) = y; |
352 | /* Variable dst = pop(); | ||
353 | |||
298 | VariableRef r = dst.getVariableRef(); | 354 | VariableRef r = dst.getVariableRef(); |
299 | setVariable( r.sName, y, r.sid ); | 355 | setVariable( r.sName, y, r.sid ); */ |
300 | } | 356 | } |
301 | break; | 357 | break; |
302 | 358 | ||
@@ -449,7 +505,7 @@ void GameState::parse( const AstBranch::NodeList &lCode ) | |||
449 | case AstNode::tAppend: | 505 | case AstNode::tAppend: |
450 | { | 506 | { |
451 | Variable v = popDeref(); | 507 | Variable v = popDeref(); |
452 | lStack.peek() += v; | 508 | deref( lStack.peek() ) += v; |
453 | } | 509 | } |
454 | break; | 510 | break; |
455 | 511 | ||
@@ -457,7 +513,16 @@ void GameState::parse( const AstBranch::NodeList &lCode ) | |||
457 | { | 513 | { |
458 | Variable v = popDeref(); | 514 | Variable v = popDeref(); |
459 | Variable k = popDeref(); | 515 | Variable k = popDeref(); |
460 | lStack.peek().insert( k, v ); | 516 | deref( lStack.peek() ).insert( k, v ); |
517 | } | ||
518 | break; | ||
519 | |||
520 | case AstNode::tIndex: | ||
521 | { | ||
522 | Variable v = popDeref(); | ||
523 | Variable cx = pop(); | ||
524 | Variable &c = deref( cx ); | ||
525 | push( Variable( &c.get( v ) ) ); | ||
461 | } | 526 | } |
462 | break; | 527 | break; |
463 | 528 | ||
@@ -505,7 +570,53 @@ void GameState::parse( const AstBranch::NodeList &lCode ) | |||
505 | break; | 570 | break; |
506 | 571 | ||
507 | case AstNode::tForEach: | 572 | case AstNode::tForEach: |
573 | { | ||
574 | AstBranch::NodeList lFe = | ||
575 | dynamic_cast<const AstBranch *>(*i)->getNodeList(); | ||
576 | AstBranch::NodeList::const_iterator iEach = lFe.begin(); | ||
577 | AstBranch::NodeList::const_iterator iIn = iEach+1; | ||
578 | AstBranch::NodeList::const_iterator iDo = iIn+1; | ||
579 | |||
580 | const AstBranch::NodeList &lEachVrs = | ||
581 | dynamic_cast<const AstBranch *>(*iEach)->getNodeList(); | ||
582 | AstBranch::NodeList::const_iterator iEachVrs = lEachVrs.begin(); | ||
583 | |||
584 | bool bUseKey = false; | ||
585 | VariableRef vrKey, vrValue; | ||
586 | if( lEachVrs.getSize() == 2 ) | ||
587 | { | ||
588 | vrKey = dynamic_cast<const AstLeafLiteral *>(*iEachVrs)-> | ||
589 | getValue().getVariableRef(); | ||
590 | iEachVrs++; | ||
591 | vrValue = dynamic_cast<const AstLeafLiteral *>(*iEachVrs)-> | ||
592 | getValue().getVariableRef(); | ||
593 | bUseKey = true; | ||
594 | } | ||
595 | else | ||
596 | { | ||
597 | vrValue = dynamic_cast<const AstLeafLiteral *>(*iEachVrs)-> | ||
598 | getValue().getVariableRef(); | ||
599 | } | ||
600 | |||
601 | parse( dynamic_cast<const AstBranch *>(*iIn)->getNodeList() ); | ||
602 | Variable vIn = popDeref(); | ||
603 | |||
604 | const AstBranch::NodeList &rDo = | ||
605 | dynamic_cast<const AstBranch *>(*iDo)->getNodeList(); | ||
508 | 606 | ||
607 | if( vIn.getType() == Variable::tDictionary ) | ||
608 | { | ||
609 | const Variable::VariableHash &rHash = vIn.getHash(); | ||
610 | for( Variable::VariableHash::const_iterator i = | ||
611 | rHash.begin(); i; i++ ) | ||
612 | { | ||
613 | if( bUseKey ) | ||
614 | setVariable( vrKey.sName, i.getKey(), vrKey.sid ); | ||
615 | setVariable( vrValue.sName, i.getValue(), vrValue.sid ); | ||
616 | parse( rDo ); | ||
617 | } | ||
618 | } | ||
619 | } | ||
509 | break; | 620 | break; |
510 | 621 | ||
511 | case AstNode::tWhile: | 622 | case AstNode::tWhile: |
diff --git a/src/gamestate.h b/src/gamestate.h index e32eeaa..5c47ce0 100644 --- a/src/gamestate.h +++ b/src/gamestate.h | |||
@@ -29,10 +29,10 @@ public: | |||
29 | 29 | ||
30 | bool hasVariable( const Bu::String &sName, ScopeId id ); | 30 | bool hasVariable( const Bu::String &sName, ScopeId id ); |
31 | void delVariable( const Bu::String &sName, ScopeId id ); | 31 | void delVariable( const Bu::String &sName, ScopeId id ); |
32 | Variable getVariable( const Bu::String &sName, ScopeId id=sidLocal ); | 32 | Variable &getVariable( const Bu::String &sName, ScopeId id=sidLocal ); |
33 | void setVariable( const Bu::String &sName, const Variable &v, ScopeId id=sidLocal ); | 33 | void setVariable( const Bu::String &sName, const Variable &v, ScopeId id=sidLocal ); |
34 | 34 | ||
35 | Variable deref( const Variable &src ); | 35 | Variable &deref( Variable &src, bool bCreate=false ); |
36 | Bu::StringList tokenize( const Bu::String &sSrc ); | 36 | Bu::StringList tokenize( const Bu::String &sSrc ); |
37 | 37 | ||
38 | void exit(); | 38 | void exit(); |
diff --git a/src/main.cpp b/src/main.cpp index 413151a..b3dbba7 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -36,7 +36,7 @@ int main( int argc, char *argv[] ) | |||
36 | while( gs.isRunning() ) | 36 | while( gs.isRunning() ) |
37 | { | 37 | { |
38 | char buf[1024]; | 38 | char buf[1024]; |
39 | sio << "command> " << sio.flush; | 39 | sio << sio.nl << "command> " << sio.flush; |
40 | fgets( buf, 1024, stdin ); | 40 | fgets( buf, 1024, stdin ); |
41 | 41 | ||
42 | gs.execCommand( buf ); | 42 | gs.execCommand( buf ); |
diff --git a/src/parser.y b/src/parser.y index 707d85d..3dfd737 100644 --- a/src/parser.y +++ b/src/parser.y | |||
@@ -155,7 +155,19 @@ cmpltExpr: expr ';' | |||
155 | | tokReturn '(' ')' ';' { bld.addNode( AstNode::tReturn ); } | 155 | | tokReturn '(' ')' ';' { bld.addNode( AstNode::tReturn ); } |
156 | | tokGoto '(' expr ')' ';' { bld.addNode( AstNode::tGoto ); } | 156 | | tokGoto '(' expr ')' ';' { bld.addNode( AstNode::tGoto ); } |
157 | | ifbase | 157 | | ifbase |
158 | | tokFor tokEach forIterator tokIn expr tokDo '{' cmpltExprList '}' | 158 | | tokFor tokEach { |
159 | bld.addNode( AstNode::tForEach ); | ||
160 | bld.addNode( AstNode::tScope ); | ||
161 | } forIterator tokIn { | ||
162 | bld.closeNode(); | ||
163 | bld.addNode( AstNode::tScope ); | ||
164 | } expr tokDo '{' { | ||
165 | bld.closeNode(); | ||
166 | bld.addNode( AstNode::tScope ); | ||
167 | } cmpltExprList '}' { | ||
168 | bld.closeNode(); | ||
169 | bld.closeNode(); | ||
170 | } | ||
159 | | tokWhile { | 171 | | tokWhile { |
160 | bld.addNode( AstNode::tWhile ); | 172 | bld.addNode( AstNode::tWhile ); |
161 | bld.addNode( AstNode::tScope ); | 173 | bld.addNode( AstNode::tScope ); |
@@ -168,8 +180,12 @@ cmpltExpr: expr ';' | |||
168 | } | 180 | } |
169 | ; | 181 | ; |
170 | 182 | ||
171 | forIterator: tokIdent | 183 | forIterator: tokIdent { bld.addVarRef( *($1), sidLocal ); } |
172 | | tokIdent ':' tokIdent | 184 | | tokIdent ':' tokIdent { |
185 | bld.addVarRef( *($1), sidLocal ); | ||
186 | bld.addVarRef( *($3), sidLocal ); | ||
187 | } | ||
188 | ; | ||
173 | 189 | ||
174 | ifbase: tokIf { | 190 | ifbase: tokIf { |
175 | bld.addNode( AstNode::tIf ); | 191 | bld.addNode( AstNode::tIf ); |
@@ -226,7 +242,8 @@ expr: literal | |||
226 | | expr tokLtEq expr { bld.addNode( AstNode::tCompLtEq ); } | 242 | | expr tokLtEq expr { bld.addNode( AstNode::tCompLtEq ); } |
227 | | expr tokGtEq expr { bld.addNode( AstNode::tCompGtEq ); } | 243 | | expr tokGtEq expr { bld.addNode( AstNode::tCompGtEq ); } |
228 | | '(' expr ')' | 244 | | '(' expr ')' |
229 | | expr '[' expr ']' | 245 | | expr '[' expr ']' { bld.addNode( AstNode::tIndex ); } |
246 | | expr '[' expr ']' '=' expr { bld.addNode( AstNode::tInsert ); } | ||
230 | | '[' ']' { bld.addLiteral( Variable( Variable::tList ) ); } | 247 | | '[' ']' { bld.addLiteral( Variable( Variable::tList ) ); } |
231 | | '[' { bld.addLiteral( Variable( Variable::tList ) ); } listValues ']' | 248 | | '[' { bld.addLiteral( Variable( Variable::tList ) ); } listValues ']' |
232 | | '{' '}' { bld.addLiteral( Variable( Variable::tDictionary ) ); } | 249 | | '{' '}' { bld.addLiteral( Variable( Variable::tDictionary ) ); } |
diff --git a/src/variable.cpp b/src/variable.cpp index 1e5cc9b..1100c84 100644 --- a/src/variable.cpp +++ b/src/variable.cpp | |||
@@ -55,6 +55,12 @@ Variable::Variable( const Bu::String &sValue ) : | |||
55 | this->sValue = new Bu::String( sValue ); | 55 | this->sValue = new Bu::String( sValue ); |
56 | } | 56 | } |
57 | 57 | ||
58 | Variable::Variable( Variable *pValue ) : | ||
59 | eType( tVarPtr ), | ||
60 | pValue( pValue ) | ||
61 | { | ||
62 | } | ||
63 | |||
58 | Variable::~Variable() | 64 | Variable::~Variable() |
59 | { | 65 | { |
60 | deinitType(); | 66 | deinitType(); |
@@ -102,6 +108,16 @@ VariableRef Variable::getVariableRef() const | |||
102 | return *rValue; | 108 | return *rValue; |
103 | } | 109 | } |
104 | 110 | ||
111 | Variable *Variable::getVariablePtr() const | ||
112 | { | ||
113 | return pValue; | ||
114 | } | ||
115 | |||
116 | const Variable::VariableHash &Variable::getHash() const | ||
117 | { | ||
118 | return *hValue; | ||
119 | } | ||
120 | |||
105 | Variable Variable::to( Type e ) const | 121 | Variable Variable::to( Type e ) const |
106 | { | 122 | { |
107 | if( e == eType ) | 123 | if( e == eType ) |
@@ -227,6 +243,14 @@ bool Variable::has( const Variable &vKey ) | |||
227 | throw Bu::ExceptionBase("Insert on non-dictionary."); | 243 | throw Bu::ExceptionBase("Insert on non-dictionary."); |
228 | } | 244 | } |
229 | 245 | ||
246 | Variable &Variable::get( const Variable &vKey ) | ||
247 | { | ||
248 | if( eType == tDictionary ) | ||
249 | return hValue->get( vKey ); | ||
250 | else | ||
251 | throw Bu::ExceptionBase("Insert on non-dictionary."); | ||
252 | } | ||
253 | |||
230 | Variable &Variable::operator=( const Variable &rhs ) | 254 | Variable &Variable::operator=( const Variable &rhs ) |
231 | { | 255 | { |
232 | deinitType(); | 256 | deinitType(); |
@@ -266,6 +290,10 @@ Variable &Variable::operator=( const Variable &rhs ) | |||
266 | case tDictionary: | 290 | case tDictionary: |
267 | (*hValue) = *rhs.hValue; | 291 | (*hValue) = *rhs.hValue; |
268 | break; | 292 | break; |
293 | |||
294 | case tVarPtr: | ||
295 | pValue = rhs.pValue; | ||
296 | break; | ||
269 | } | 297 | } |
270 | } | 298 | } |
271 | 299 | ||
@@ -725,11 +753,11 @@ void Variable::initType() | |||
725 | break; | 753 | break; |
726 | 754 | ||
727 | case tList: | 755 | case tList: |
728 | lValue = new VList(); | 756 | lValue = new VariableList(); |
729 | break; | 757 | break; |
730 | 758 | ||
731 | case tDictionary: | 759 | case tDictionary: |
732 | hValue = new VHash(); | 760 | hValue = new VariableHash(); |
733 | break; | 761 | break; |
734 | } | 762 | } |
735 | } | 763 | } |
@@ -821,6 +849,9 @@ Bu::Formatter &operator<<( Bu::Formatter &f, const Variable &v ) | |||
821 | 849 | ||
822 | case Variable::tDictionary: | 850 | case Variable::tDictionary: |
823 | return f << *v.hValue; | 851 | return f << *v.hValue; |
852 | |||
853 | case Variable::tVarPtr: | ||
854 | return f << "(varptr:" << *v.pValue << ")"; | ||
824 | } | 855 | } |
825 | 856 | ||
826 | return f << "ERROR"; | 857 | return f << "ERROR"; |
diff --git a/src/variable.h b/src/variable.h index 97308c7..22a1b26 100644 --- a/src/variable.h +++ b/src/variable.h | |||
@@ -44,23 +44,30 @@ public: | |||
44 | Variable( double fValue ); | 44 | Variable( double fValue ); |
45 | Variable( bool bValue ); | 45 | Variable( bool bValue ); |
46 | Variable( const Bu::String &sValue ); | 46 | Variable( const Bu::String &sValue ); |
47 | Variable( Variable *pValue ); | ||
47 | virtual ~Variable(); | 48 | virtual ~Variable(); |
48 | 49 | ||
49 | static Variable newSituationName( const Bu::String &s ); | 50 | static Variable newSituationName( const Bu::String &s ); |
50 | static Variable newVariableName( const Bu::String &s, ScopeId sid ); | 51 | static Variable newVariableName( const Bu::String &s, ScopeId sid ); |
51 | 52 | ||
52 | Type getType() const { return eType; } | 53 | Type getType() const { return eType; } |
54 | |||
55 | typedef Bu::List<Variable> VariableList; | ||
56 | typedef Bu::Hash<Variable, Variable> VariableHash; | ||
53 | 57 | ||
54 | bool getBool() const; | 58 | bool getBool() const; |
55 | int64_t getInt() const; | 59 | int64_t getInt() const; |
56 | double getFloat() const; | 60 | double getFloat() const; |
57 | Bu::String getString() const; | 61 | Bu::String getString() const; |
58 | VariableRef getVariableRef() const; | 62 | VariableRef getVariableRef() const; |
63 | Variable *getVariablePtr() const; | ||
64 | const VariableHash &getHash() const; | ||
59 | 65 | ||
60 | Variable to( Type e ) const; | 66 | Variable to( Type e ) const; |
61 | 67 | ||
62 | void insert( const Variable &vKey, const Variable &vValue ); | 68 | void insert( const Variable &vKey, const Variable &vValue ); |
63 | bool has( const Variable &vKey ); | 69 | bool has( const Variable &vKey ); |
70 | Variable &get( const Variable &vKey ); | ||
64 | 71 | ||
65 | Variable &operator=( const Variable &rhs ); | 72 | Variable &operator=( const Variable &rhs ); |
66 | Variable &operator+=( const Variable &rhs ); | 73 | Variable &operator+=( const Variable &rhs ); |
@@ -86,17 +93,14 @@ private: | |||
86 | private: | 93 | private: |
87 | Type eType; | 94 | Type eType; |
88 | 95 | ||
89 | typedef Bu::List<Variable> VList; | ||
90 | typedef Bu::Hash<Variable, Variable> VHash; | ||
91 | |||
92 | union | 96 | union |
93 | { | 97 | { |
94 | int64_t iValue; | 98 | int64_t iValue; |
95 | double fValue; | 99 | double fValue; |
96 | bool bValue; | 100 | bool bValue; |
97 | Bu::String *sValue; | 101 | Bu::String *sValue; |
98 | VList *lValue; | 102 | VariableList *lValue; |
99 | VHash *hValue; | 103 | VariableHash *hValue; |
100 | VariableRef *rValue; | 104 | VariableRef *rValue; |
101 | Variable *pValue; | 105 | Variable *pValue; |
102 | }; | 106 | }; |
@@ -7,10 +7,44 @@ game.start = <<start>>; | |||
7 | 7 | ||
8 | global | 8 | global |
9 | { | 9 | { |
10 | command: "eat" object | 10 | command: "go" dir |
11 | { | 11 | { |
12 | display(object); | 12 | if exists(situation.exits) then |
13 | { | ||
14 | if dir in situation.exits then | ||
15 | { | ||
16 | goto( situation.exits[dir] ); | ||
17 | } | ||
18 | } | ||
19 | display('''You're not really sure how to do that...'''); | ||
20 | } | ||
21 | |||
22 | command: "exits" | ||
23 | { | ||
24 | if exists(situation.exits) then | ||
25 | { | ||
26 | out = "Obvious exits are: "; | ||
27 | bFirst = true; | ||
28 | for each dir : dest in situation.exits do | ||
29 | { | ||
30 | if bFirst then | ||
31 | { | ||
32 | bFirst = false; | ||
33 | } | ||
34 | else | ||
35 | { | ||
36 | out += ", "; | ||
37 | } | ||
38 | out += dir; | ||
39 | } | ||
40 | display( out ); | ||
41 | } | ||
42 | else | ||
43 | { | ||
44 | display("There are no obvious exits."); | ||
45 | } | ||
13 | } | 46 | } |
47 | |||
14 | // You should always have a global exit, quit, escape, something for | 48 | // You should always have a global exit, quit, escape, something for |
15 | // dev-testing at least. | 49 | // dev-testing at least. |
16 | command: "exit" | 50 | command: "exit" |
@@ -50,54 +84,58 @@ function getThing() | |||
50 | 84 | ||
51 | situation <<start>> | 85 | situation <<start>> |
52 | { | 86 | { |
53 | command: "go" "home" | 87 | setup |
54 | { | 88 | { |
55 | display("Home would be nice..."); | 89 | goto( <<diningRoom>> ); |
56 | } | 90 | } |
57 | 91 | ||
58 | command: "go" elsewhere | 92 | enter |
59 | { | 93 | { |
60 | display("You don't know how to go " + elsewhere ); | ||
61 | } | 94 | } |
95 | } | ||
96 | |||
97 | situation <<diningRoom>> | ||
98 | { | ||
62 | setup | 99 | setup |
63 | { | 100 | { |
64 | stuff = {"things": 55, 112: "Bob"}; | 101 | situation.exits = { |
65 | display( stuff ); | 102 | 'south': <<livingRoom>>, |
66 | display( 113 - 1 in stuff ); | 103 | 'east': <<kitchen>> |
67 | exit(); | 104 | }; |
68 | } | 105 | } |
69 | |||
70 | enter | 106 | enter |
71 | { | 107 | { |
72 | display('''This is the enter part of the start situation'''); | 108 | display('''You are in the dining room, it's very nice and warm. There |
109 | is a big table and...stuff. Looks like the living room is south, and | ||
110 | the kitchen is to the east.'''); | ||
73 | } | 111 | } |
74 | } | 112 | } |
75 | 113 | ||
76 | situation <<stuff>> | 114 | situation <<livingRoom>> |
77 | { | 115 | { |
78 | command: "eat" object | 116 | setup |
79 | { | 117 | { |
80 | display("You can't eat " + object ); | 118 | situation.exits = { |
119 | 'north': <<diningRoom>> | ||
120 | }; | ||
81 | } | 121 | } |
82 | 122 | enter | |
83 | command: "eat" object "now" | ||
84 | { | 123 | { |
85 | display("Alright, fine, eat " + object + " now..." ); | 124 | display('''Living room!'''); |
86 | } | 125 | } |
126 | } | ||
87 | 127 | ||
128 | situation <<kitchen>> | ||
129 | { | ||
88 | setup | 130 | setup |
89 | { | 131 | { |
90 | situation.thing = "Just a thing"; | 132 | situation.exits = { |
133 | 'west': <<diningRoom>> | ||
134 | }; | ||
91 | } | 135 | } |
136 | |||
92 | enter | 137 | enter |
93 | { | 138 | { |
94 | getThing(); | 139 | display('''Kitchen!'''); |
95 | display('''Entered stuff''' + player.name); | ||
96 | count = 0; | ||
97 | while count < 5 do | ||
98 | { | ||
99 | display('thing to count!'); | ||
100 | count += 1; | ||
101 | } | ||
102 | } | 140 | } |
103 | } | 141 | } |